#include <string.h>

char *___strtok = NULL;

char *strcpy(char *dest, const char *src)
{
    char *tmp = dest;

    while ((*dest++ = *src++) != '\0')
        /* nothing */;
    return tmp;
}

char *strncpy(char *dest, const char *src, size_t count)
{
    char *tmp = dest;

    while (count-- && (*dest++ = *src++) != '\0')
        /* nothing */;

    return tmp;
}

char *strcat(char *dest, const char *src)
{
    char *tmp = dest;

    while (*dest)
        dest++;
    while ((*dest++ = *src++) != '\0')
        ;

    return tmp;
}

char *strncat(char *dest, const char *src, size_t count)
{
    char *tmp = dest;

    if (count) {
        while (*dest)
            dest++;
        while ((*dest++ = *src++)) {
            if (--count == 0)
                break;
        }
    }

    return tmp;
}

int strcmp(const char *cs, const char *ct)
{
    register signed char __res;

    while (1) {
        if ((__res = *cs - *ct++) != 0 || !*cs++)
            break;
    }

    return __res;
}

int strncmp(const char *cs, const char *ct, size_t count)
{
    register signed char __res = 0;

    while (count) {
        if ((__res = *cs - *ct++) != 0 || !*cs++)
            break;
        count--;
    }

    return __res;
}

char *strchr(const char *s, int c)
{
    for(; *s != c; ++s)
        if (*s == '\0')
            return NULL;
    return (char *) s;
}

size_t strlen(const char *s)
{
    const char *sc;

    for (sc = s; *sc != '\0'; ++sc)
        /* nothing */;
    return sc - s;
}

size_t strnlen(const char *s, size_t count)
{
    const char *sc;

    for (sc = s; *sc != '\0' && count--; ++sc)
        /* nothing */;
    return sc - s;
}

size_t strspn(const char *s, const char *accept)
{
    const char *p;
    const char *a;
    size_t count = 0;

    for (p = s; *p != '\0'; ++p) {
        for (a = accept; *a != '\0'; ++a) {
            if (*p == *a)
                break;
        }
        if (*a == '\0')
            return count;
        ++count;
    }

    return count;
}

char *strpbrk(const char *cs, const char *ct)
{
    const char *sc1, *sc2;

    for( sc1 = cs; *sc1 != '\0'; ++sc1) {
        for( sc2 = ct; *sc2 != '\0'; ++sc2) {
            if (*sc1 == *sc2)
                return (char *) sc1;
        }
    }
    return NULL;
}

char *strtok(char *s, const char *ct)
{
    char *sbegin, *send;

    sbegin  = s ? s : ___strtok;
    if (!sbegin) {
        return NULL;
    }
    sbegin += strspn(sbegin, ct);
    if (*sbegin == '\0') {
        ___strtok = NULL;
        return( NULL );
    }
    send = strpbrk(sbegin, ct);
    if (send && *send != '\0') {
        *send++ = '\0';
    }
    ___strtok = send;
    return (sbegin);
}

void *memset(void *s, int c, size_t count)
{
    char *xs = (char *) s;

    while (count--)
        *xs++ = c;

    return s;
}

char *bcopy(const char *src, char *dest, int count)
{
    char *tmp = dest;

    while (count--)
        *tmp++ = *src++;

    return dest;
}

void *memcpy(void *dest, const void *src, size_t count)
{
    char *tmp = (char *) dest, *s = (char *) src;

    while (count--)
        *tmp++ = *s++;

    return dest;
}

void *memmove(void *dest, const void *src, size_t count)
{
    char *tmp, *s;

    if (dest <= src) {
        tmp = (char *)dest;
        s = (char *)src;
        while (count--)
            *tmp++ = *s++;
        }
    else {
        tmp = (char *)dest + count;
        s = (char *)src + count;
        while (count--)
            *--tmp = *--s;
        }

    return dest;
}

int memcmp(const void *cs, const void *ct, size_t count)
{
    const unsigned char *su1, *su2;
    signed char res = 0;

    for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) {
        if ((res = *su1 - *su2) != 0)
            break;
    }
    return res;
}

/*
 * find the first occurrence of byte 'c', or 1 past the area if none
 */
void *memscan(void *addr, int c, size_t size)
{
    unsigned char *p = (unsigned char *)addr;

    while (size) {
        if (*p == c)
            return (void *)p;
        p++;
        size--;
    }
    return (void *)p;
}
